#include <iostream>
#include <functional>
#include <map>
#include <string>
#include <memory>
#include <string.h>


typedef std::function<const void* ()> Func;

class Test1
{
    public:
        std::string Name(){return "Test1";}
        int a =0;
};
class Test2
{
    public:
        std::string Name(){return "Test2";}
        std::string a = "hello world";
};



class Manage
{
    public:
        const void* GetTest1(){return &t1;}
        const void* GetTest2(){return &t2;}
        void Load()
        {
            l.insert(std::make_pair("Test1",std::bind(&Manage::GetTest1,this)));
            l.insert(std::make_pair("Test2",std::bind(&Manage::GetTest2,this)));
        }
        template<typename T>
        const T* GetConfig()
        {
            T t;
            auto it = l.find(t.Name());
            if(it == l.end())
                return nullptr;
            auto fuc = it->second;
            return (const T*)fuc();
        }
    private:
        std::map<std::string ,Func> l;
        Test1 t1;
        Test2 t2;
};

class Show1
{
    public:
        Show1()
        {
            std::cout<<"ccccc"<<std::endl;
        }
        ~Show1()
        {
            std::cout<<"ddddddd"<<std::endl;
        }
};

class ShowClass
{
    public:
        ShowClass()
        {
            std::cout<<"ShowClass()"<<std::endl;
        }
        ~ShowClass()
        {
            std::cout<<"~ShowClass()"<<std::endl;
        }
};

class SingleFunction
{
    public:
         static ShowClass& GetShow() { return show; }; 
    private:
        static  ShowClass show;
};
ShowClass SingleFunction::show;

class Div : public SingleFunction
{
};
class DivS:public SingleFunction
{
};




struct Nodes
{
    Nodes(){c = NULL;}
    int a;
    int b;
    char* c;
};


class PublicShow
{
    public:
        class Root
        {
            private:
                friend class PublicShow;
                void show()
                {
                    std::cout<<"this is private function()"<<std::endl;
                }
        };
        PublicShow()
        {
            root = new Root();
        }
        void Show()
        {
            root->show();
        }
    private:
        Root* root;

};

int main()
{
    Manage m;
    m.Load();
    const Test1* t1 = m.GetConfig<Test1>();
    std::cout<<t1->a<<std::endl;
    const Test2* t2 = m.GetConfig<Test2>();
    std::cout<<t2->a<<std::endl;

    {
        std::unique_ptr<Show1> a (new Show1());
        std::unique_ptr<Show1> b = std::move(a);
    }

    char* buf = "112345";

    Nodes* one = new Nodes();
    one->c = buf;
    std::cout<<"addr:"<<one +1<<"\t addrs:"<<&(one->c)<<"\tadd"<<&(buf)<<std::endl;
    char* bufs =(char*) malloc(100);
    memcpy(bufs,one->c,99);
    bufs[99] = '\0';
    std::cout<<bufs<<std::endl;


    Div* div1 = new Div();
    Div* div2 = new Div();
    Div* div3 = new Div();
    Div* div4 = new Div();
    Div* div5 = new Div();
    Div* div6 = new Div();
    DivS* div7 = new DivS();

   
    delete div1;
    delete div2;
    delete div3;
    delete div4;
    delete div5;
    delete div6;
    delete div7;
    PublicShow* pshow  = new PublicShow();
    pshow->Show();

    return 0;
}
